feat: version display + one-click upgrades via Watchtower#103
feat: version display + one-click upgrades via Watchtower#103MichaelCordner wants to merge 3 commits intomainfrom
Conversation
- Always show current version in sidebar footer - Watchtower sidecar in monitor-only + HTTP API mode (checks daily, never auto-updates) - POST /admin/upgrade endpoint (human session required) triggers Watchtower to pull + restart - /version endpoint returns upgrade_available flag - UI banner shows "Update now" button when Watchtower is configured, falls back to release link - jentic-update.sh host-side fallback script - README documenting update options Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The sessionStorage cache persisted across upgrades, showing a stale "update available" banner even after the update was applied. Now the cache is validated against /health on load — if the running version differs from the cached currentVersion, the cache is discarded and a fresh check runs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
char0n
left a comment
There was a problem hiding this comment.
Review
Good feature — version visibility + one-click upgrades with correct security model (human-only, token-authenticated Watchtower, scoped to jentic container). Four items to fix before merge:
Must fix
1. Missing credentials: 'include' on upgrade fetch (Layout.tsx)
await fetch('/admin/upgrade', { method: 'POST' })No session cookie sent → endpoint always returns 403. Should be:
await fetch('/admin/upgrade', { method: 'POST', credentials: 'include' })2. Watchtower response not checked (main.py:288)
The response from Watchtower is ignored — a 401 (bad token) or 500 still returns "status": "update_triggered". Should check resp.status_code and return an error if Watchtower rejects the request.
3. upgrade_available is misleading (main.py:262)
"upgrade_available": bool(os.getenv("WATCHTOWER_API_URL")),Returns true if Watchtower is configured, not if an upgrade exists. The UI uses this to decide between "Update now" button vs "View release notes" link. Rename to watchtower_configured or upgrade_mechanism_available.
4. Hardcoded amber colors (Layout.tsx)
PR #83 replaced all hardcoded Tailwind colors with semantic design tokens. This reintroduces amber-* classes (text-amber-600, bg-amber-50, etc.). Should use text-warning, bg-warning/10 or the accent-yellow tokens from index.css.
Nice to have
5. Duplicate from fastapi import HTTPException — imported inline 3x in trigger_upgrade() but already imported at top of main.py.
6. Cache flash — useUpdateCheck.ts sets stale cached status immediately, then fires async /health check to validate. User briefly sees old "update available" banner before correction. Minor UX.
There was a problem hiding this comment.
Pull request overview
Adds UI version visibility and an update/upgrade flow driven by backend /version metadata and a new human-only /admin/upgrade endpoint, with a Watchtower sidecar provided via compose.yml plus a CLI fallback script.
Changes:
- UI: display current version in the sidebar footer and show an “update available” banner with either “Update now” (Watchtower) or “View release notes”.
- Backend: extend
/versionwithupgrade_availableand addPOST /admin/upgradeto trigger a Watchtower HTTP API update. - Deployment/docs: add Watchtower sidecar configuration, a
jentic-update.shhost script, and a README “Updating” section.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/src/hooks/useUpdateCheck.ts | Adds upgradeAvailable and adjusts sessionStorage caching + version validation logic |
| ui/src/components/layout/Layout.tsx | Adds sidebar version footer and update banner/button UI |
| src/main.py | Adds upgrade_available on /version and introduces /admin/upgrade Watchtower trigger endpoint |
| compose.yml | Adds Watchtower sidecar service and scopes/vars to enable on-demand updates |
| jentic-update.sh | Adds a host-side manual update script using docker compose pull/up |
| README.md | Documents update options (UI/Watchtower, script, manual) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Additional items from Copilot reviewThree more worth addressing: 7. Pin Watchtower version (compose.yml:29)
8. Upgrade button stuck on error (Layout.tsx:103)
9.
Also noted by Copilot but lower priority:
|
Summary
Adds version visibility in the UI and a one-click upgrade path so users never have to SSH in to update.
What changed
UI sidebar footer — always shows the current version (e.g.
v0.2.5).Update banner — when a newer release exists on GitHub:
POST /admin/upgradeendpoint — human session required. Calls Watchtower's HTTP API to trigger an image pull + container restart. Returns immediately; the app briefly goes offline and comes back on the new version. Agents cannot call this endpoint (403 for non-human sessions).Watchtower sidecar in
compose.yml— runs in monitor-only mode by default:WATCHTOWER_MONITOR_ONLY=true— checks for new images daily but never applies them automaticallyWATCHTOWER_HTTP_API_UPDATE=true— exposes an internal HTTP endpoint for on-demand updatesWATCHTOWER_SCOPE=jentic— scoped to only the jentic-mini container (won't touch other containers on the host)WATCHTOWER_TOKENenv var, defaults tojentic-update)/versionendpoint — now returnsupgrade_available: true/falseso the UI knows whether to show the button or the fallback link.jentic-update.sh— host-side fallback script for users who don't use the compose file with Watchtower:docker compose pull && docker compose up -d.README — new "Updating" section documenting all three upgrade paths (UI button, script, manual commands).
Files changed
ui/src/components/layout/Layout.tsxui/src/hooks/useUpdateCheck.tsupgradeAvailabletoUpdateStatusinterfacecompose.ymlsrc/main.pyPOST /admin/upgradeendpoint +upgrade_availablefield on/versionjentic-update.shREADME.mdSecurity notes
/admin/upgraderequires a human session (is_human_sessioncheck) — agents get 403How to test
docker compose up -d— both jentic-mini and watchtower startAPP_VERSION=0.0.1as a build arg)/admin/upgrade, Watchtower pulls the latest image and restarts the containerdocker compose stop watchtower, verify the banner falls back to showing the release link instead of the button🤖 Generated with Claude Code